package service.impl;

import base.ActionContext;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiType;
import service.SqlGenerator;
import util.FileUtil;
import util.SqlGenUtil;
import util.psi.NameUtils;
import util.psi.PsiClassUtil;

import java.io.IOException;
import java.util.*;

/**
 * 杭州蓝诗网络科技有限公司 版权所有 © Copyright 2018<br>
 *
 * @Description: <br>
 * @Project: hades <br>
 * @CreateDate: Created in 2018/8/22 09:36 <br>
 * @Author: <a href="yechangjun@quannengzhanggui.com">lomoye</a>
 */

public class SqlGeneratorImpl implements SqlGenerator {

    private LinkedList<String> fieldNames = new LinkedList<>();//所有的字段

    private Map<String/*field*/, String/*field-type*/> fieldTypeMap = new HashMap<>();

    private Map<String/*field*/, String/*note*/> noteMap = new HashMap<>();

    private Map<String/*field*/, Boolean/*NotNull*/> notNullMap = new HashMap<>();

    public void init(ActionContext context) {
        PsiClass clazz = context.getPsiClass();

        PsiField[] fs = clazz.getAllFields();
        for (PsiField f : fs) {
            String fieldType = getFiledType(f.getType());
            if (!isSupportFiledType(fieldType)) {
                continue;
            }
            fieldNames.add(f.getName());
            fieldTypeMap.put(f.getName(), fieldType);
            noteMap.put(f.getName(), PsiClassUtil.getNote(f));
            notNullMap.put(f.getName(), PsiClassUtil.getIsNotNull(f));
        }

        //特殊处理一下
        fieldNames.remove("id");
        fieldNames.addFirst("id");
        fieldTypeMap.put("id", "Long");
    }

    /**
     * 生成sql
     */
    @Override
    public String makeSql(ActionContext context) {
        init(context);

        StringBuilder sqlBuilder = new StringBuilder();

        sqlBuilder.append("DROP TABLE IF EXISTS ")
                .append(NameUtils.camelToUnderline(context.getClassName()))
                .append(";\n")
                .append("CREATE TABLE ")
                .append(NameUtils.camelToUnderline(context.getClassName()))
                .append("(\n");

        for (String name : fieldNames) {
            String fieldType = fieldTypeMap.get(name);
            String line = SqlGenUtil.genColumnLine(NameUtils.camelToUnderline(name), fieldType);
            if ("id".equalsIgnoreCase(name)) {
                line = line + " NOT NULL AUTO_INCREMENT";
            } else if (notNullMap.get(name)) {
                line = line + " NOT NULL";
            }

            if (noteMap.get(name) != null) {
                line = line + " COMMENT \'" + noteMap.get(name) + "\'";
            }

            sqlBuilder.append(line).append(",\n");
        }

        sqlBuilder.append("PRIMARY KEY (id) \n")
                .append(") ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;");

        return sqlBuilder.toString();
    }

    /**
     * 保存sql到本地文件
     */
    @Override
    public void saveSql(String fileName, String content, String path) throws IOException {
        FileUtil.write(fileName + ".sql", content, path);
    }

    private String getFiledType(PsiType cl) {
        if (PsiClassUtil.isEnum(cl)) {
            return "Enum";
        }

        String name = cl.toString();
        return name.substring(name.indexOf(":") + 1);
    }


    private boolean isSupportFiledType(String fieldType) {
        String dbFiledType = SqlGenUtil.getFiledType(fieldType);
        return dbFiledType != null;
    }

}
